package com.lzd.main.controller;

import cn.hutool.core.codec.Base62;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.lzd.main.bdmap.BaiduMapWebApi;
import com.lzd.main.dao.AntiFake;
import com.lzd.main.dao.Result;
import com.lzd.main.dao.AntiFakeDao;
import com.lzd.main.dao.TrackModel;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@CrossOrigin(origins = "*")
@RestController
public class AntiCodeController {

    private static final Logger logger = LoggerFactory.getLogger(AntiCodeController.class);

    @Value("${server.hosturl}")
    private String hostUrl;

    @Autowired
    private AntiFakeDao antiDao;


    /**
     * 产品绑定，需要记录当前百度地图坐标，开始溯源
     * @return
     * @throws SQLException
     */
    @RequestMapping("/code/bind")
    public void codeBindProd(HttpServletResponse response) throws SQLException, IOException, NoSuchAlgorithmException {

        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        long id = snowflake.nextId();
        String uuid = IdUtil.randomUUID();
        long time = System.currentTimeMillis();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String currentDay = simpleDateFormat.format(new Date(time));


        String data = currentDay+id+uuid;
        logger.info("签名前:{},{}",data,data.getBytes());
        //签名

        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(data.getBytes());
        /*
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < hash.length; i++) {
            String hex = Integer.toHexString(0xff & hash[i]);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        */

        data = Base62.encode(hash);
        logger.info("签名后:{}",data);

        ServletOutputStream out = null;
        try {
            antiDao.save(id,uuid,time);
            out = response.getOutputStream();
            BufferedImage bufferedImage = QrCodeUtil.generate(hostUrl+"/code/verify?id="+id+"&sign="+data, 500,500);
            ImageIO.write(bufferedImage, "png", out);
            out.flush();
        } catch (IOException e) {
            throw e;
        } finally {
            if(out !=null ){
                out.close();
            }
        }
    }

    /**
     * 产品验证，并获得路线图
     * @return
     * @throws SQLException
     */
    @GetMapping("/code/verify")
    public Result<Map<String,Object>> verify(@RequestParam Long id, @RequestParam(value="sign") String signed,
          @RequestParam(value="address") String address, @RequestParam(value="lng") double lng, @RequestParam(value="lat") double lat) throws SQLException, NoSuchAlgorithmException {
        logger.info("验证,id:{},sign:{}", id, signed);
        Result<Map<String,Object>> result = new Result<>();
        if(signed==null || id==null){
            result.setErr(1409);
            result.setSuccess(false);
            return result;
        }

        AntiFake antiFake = antiDao.getById(id);
        if(antiFake==null){
            result.setErr(1404);
            result.setSuccess(false);
            return result;
        }

        String data = antiFake.getDate().toString()+id+antiFake.getCode();

        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(data.getBytes());

        String sign = Base62.encode(hash);
        logger.info("签名前:{},{},{}", data, sign, data.getBytes());

        if(signed.equals(sign)){
            //计算路线
            String RouteArr = antiFake.getRoute();
            System.out.println("原路线："+RouteArr);
            JSONArray jsonObject = JSONUtil.parseArray(null);
            if(RouteArr!=null){
                if(!RouteArr.trim().equals("")){
                    jsonObject = JSONUtil.parseArray(RouteArr);
                }
            }

            if(lng==antiFake.getPointLng() && lat==antiFake.getPointLat()){

            }else{
                String startPoint = antiFake.getPointLat()+","+antiFake.getPointLng();
                if("0.0,0.0".equals(startPoint)){
                    startPoint = "39.914880077046746,116.41389099999994";
                }

                System.out.println("起始点："+startPoint);
                String endPoint = lat+","+lng;
                System.out.println("终点："+endPoint);
                List<Double[]> luxian = BaiduMapWebApi.routePointArr(startPoint, endPoint);
                jsonObject.addAll(luxian);
            }

            //添加验证记录，返回溯源记录列表
            List<TrackModel> list = antiDao.getList(id,address,lng,lat,jsonObject);

            Map<String,Object> rdata = new HashMap<>();
            rdata.put("data", list);
            rdata.put("line", jsonObject);

            result.setData(rdata);
            result.setSuccess(true);
            return result;
        }else{
            //添加验证错误
            antiDao.addErrRecord(id,address,lng,lat);

            result.setErr(1400);
            result.setSuccess(false);
            return result;
        }
    }
}
